//////////////////////////////////////////////////////////////////////////

#ifndef _CONNECTIONIMPL_H_
#define _CONNECTIONIMPL_H_

//////////////////////////////////////////////////////////////////////////

#ifndef _OBSERVABLE_H_
#include "observable.h"
#endif

#ifndef _NETWORKPACKET_H_
#include "networkpacket.h"
#endif

//////////////////////////////////////////////////////////////////////////


/** Interface class for connection between client and server
*
*  @author   Pasechnik Roman
*  @since    Aug 18th, 2009
*  @updated  Sep 08th, 2009
*/
class ConnectionImpl : public Observable
{
//////////////////////////////////////////////////////////////////////////

public:

//////////////////////////////////////////////////////////////////////////


    /** Constructor */
    ConnectionImpl();


    /** Destructor */
    virtual ~ConnectionImpl();


//////////////////////////////////////////////////////////////////////////


    /** Factory methods */
    static ConnectionImpl* GetServerConnectionImpl();
    static ConnectionImpl* GetClientConnectionImpl();


//////////////////////////////////////////////////////////////////////////


    /** Send TCP */
    virtual void SendTCP( const NetworkPacket& _data ) = 0;


    /** Send UDP */
    virtual void SendUDP( const NetworkPacket& _data ) = 0;


//////////////////////////////////////////////////////////////////////////


    /** Recv TCP */
    const NetworkPacket& GetRecvDataTCP() const;


    /** Recv UDP */
    const NetworkPacket& GetRecvDataUDP() const;


//////////////////////////////////////////////////////////////////////////


    /** Connect to server (client only) */
    virtual void Connect( const char* _address ) = 0;


    /** Accept new connection (server only) */
    virtual void Accept() = 0;


    /** Close connection */
    virtual void Close() = 0;


//////////////////////////////////////////////////////////////////////////


    /** Is client connected to server */
    virtual bool IsConnected() const = 0;


//////////////////////////////////////////////////////////////////////////

protected:

//////////////////////////////////////////////////////////////////////////


    /** Max buffer size for incoming network packets */
    enum { MAX_BUFFER_SIZE = 1024 };


    /** Buffer for received TCP data */
    char m_RecvBufferTCP[MAX_BUFFER_SIZE];


    /** Packet with received data via TCP */
    NetworkPacket m_RecvPacketTCP;


    /** Buffer for received UDP data */
    static char m_RecvBufferUDP[MAX_BUFFER_SIZE];


    /** Packet with received data via UDP */
    static NetworkPacket m_RecvPacketUDP;


//////////////////////////////////////////////////////////////////////////


    /** Handle accept */
    void HandleAccept();


    /** Handle sent packet */
    void HandleSendTCP();
    void HandleSendUDP();


    /** Handle received packet */
    void HandleRecvTCP();
    void HandleRecvUDP();


    /** Disconnect handler */
    void HandleDisconnect();


//////////////////////////////////////////////////////////////////////////


    /** Port number */
    static const size_t m_Port;
    static const char* m_PortStr;


//////////////////////////////////////////////////////////////////////////
};


//////////////////////////////////////////////////////////////////////////

#endif

//////////////////////////////////////////////////////////////////////////
